//
// MethodFactory.h
// Factory for the supported iterative methods.
//
// Author: Gabriel H. Barbuto (gbarbuto@dc.uba.ar)
//
#ifndef _METHOD_FACTORY_H_
#define _METHOD_FACTORY_H_

#include <functional>
#include <map>
#include <memory>
#include <string>

#include "IterativeMethod.h"

class MethodFactory
{
public:

	inline static const MethodFactory &instance()
	{
		if (_unique_instance == 0)
		{
			_unique_instance = std::unique_ptr<MethodFactory>(new MethodFactory());
		}

		return *_unique_instance;
	}

	IterativeMethod *get(std::string const &function_name, std::string const &method_name, double const &alpha) const;

	static const std::string DIRECT_FUNCTION_NAME;
	static const std::string INVERSE_FUNCTION_NAME;

	static const std::string BISECTION_METHOD_NAME;
	static const std::string NEWTON_METHOD_NAME;
	static const std::string SECANT_METHOD_NAME;

private:

	MethodFactory();

	void initialize_methods();

	std::map<std::string, std::map<std::string, std::function<IterativeMethod *(double const &)>>> _methods;

	static std::unique_ptr<MethodFactory> _unique_instance;
};

#endif
